package com.campus.help.service;

import com.alibaba.fastjson.JSONObject;
import com.campus.help.config.WechatConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.TimeUnit;

/**
 * 微信内容安全检测服务
 *
 * @author campus-help
 * @since 2025-11-24
 */
@Slf4j
@Service
public class WeChatSecurityService {

    @Autowired
    private WechatConfig wechatConfig;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String ACCESS_TOKEN_KEY = "wechat:access_token";
    private static final String MSG_SEC_CHECK_URL = "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=";

    /**
     * 获取微信Access Token
     */
    private String getAccessToken() {
        // 先从Redis缓存中获取
        String cachedToken = redisTemplate.opsForValue().get(ACCESS_TOKEN_KEY);
        if (cachedToken != null && !cachedToken.isEmpty()) {
            log.info("从缓存获取Access Token");
            return cachedToken;
        }

        // 缓存中没有，从微信服务器获取
        String url = wechatConfig.getApiBaseUrl() + wechatConfig.getAccessTokenUrl()
                + "?grant_type=client_credential"
                + "&appid=" + wechatConfig.getAppId()
                + "&secret=" + wechatConfig.getAppSecret();

        try {
            String response = restTemplate.getForObject(url, String.class);
            JSONObject jsonObject = JSONObject.parseObject(response);

            if (jsonObject.containsKey("access_token")) {
                String accessToken = jsonObject.getString("access_token");
                Integer expiresIn = jsonObject.getInteger("expires_in");

                // 缓存到Redis，提前5分钟过期以避免边界问题
                redisTemplate.opsForValue().set(ACCESS_TOKEN_KEY, accessToken, expiresIn - 300, TimeUnit.SECONDS);

                log.info("从微信服务器获取Access Token成功");
                return accessToken;
            } else {
                log.error("获取Access Token失败: {}", response);
                throw new RuntimeException("获取微信Access Token失败: " + jsonObject.getString("errmsg"));
            }
        } catch (Exception e) {
            log.error("获取Access Token异常", e);
            throw new RuntimeException("获取微信Access Token异常: " + e.getMessage());
        }
    }

    /**
     * 检测文本内容安全
     *
     * @param content 待检测的文本内容
     * @return true-内容安全，false-内容违规
     */
    public boolean checkTextSecurity(String content) {
        if (content == null || content.trim().isEmpty()) {
            return true;
        }

        try {
            String accessToken = getAccessToken();
            String url = MSG_SEC_CHECK_URL + accessToken;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("version", 2); // 使用v2版本
            requestBody.put("scene", 2); // 场景值：2-内容安全
            requestBody.put("openid", "oABCD_default_openid"); // 用户的openid（可选）
            requestBody.put("content", content);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<String> entity = new HttpEntity<>(requestBody.toJSONString(), headers);

            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
            JSONObject result = JSONObject.parseObject(response.getBody());

            log.info("内容安全检测结果: {}", result.toJSONString());

            // 检查返回结果
            Integer errCode = result.getInteger("errcode");
            if (errCode == 0) {
                // errcode为0表示检测成功
                JSONObject resultObj = result.getJSONObject("result");
                if (resultObj != null) {
                    String suggest = resultObj.getString("suggest");
                    // suggest: pass-通过, review-需人工审核, risky-有风险
                    if ("pass".equals(suggest)) {
                        return true;
                    } else {
                        log.warn("内容安全检测未通过: suggest={}, content={}", suggest, content);
                        return false;
                    }
                }
                return true;
            } else {
                log.error("内容安全检测API调用失败: errcode={}, errmsg={}", errCode, result.getString("errmsg"));
                // API调用失败时，为了不影响用户体验，返回true（但记录日志）
                return true;
            }
        } catch (Exception e) {
            log.error("内容安全检测异常", e);
            // 异常时返回true，避免影响正常业务流程
            return true;
        }
    }

    /**
     * 检测劳务内容安全（检测标题和描述）
     *
     * @param title 劳务标题
     * @param description 劳务描述
     * @return true-内容安全，false-内容违规
     */
    public boolean checkLaborContentSecurity(String title, String description) {
        // 检测标题
        if (!checkTextSecurity(title)) {
            log.warn("劳务标题包含违规内容: {}", title);
            return false;
        }

        // 检测描述
        if (!checkTextSecurity(description)) {
            log.warn("劳务描述包含违规内容: {}", description);
            return false;
        }

        return true;
    }
}
